#css border color
Explore tagged Tumblr posts
Text
How to Create Multi-Step Forms With Vanilla JavaScript and CSS
New Post has been published on https://thedigitalinsider.com/how-to-create-multi-step-forms-with-vanilla-javascript-and-css/
How to Create Multi-Step Forms With Vanilla JavaScript and CSS
Multi-step forms are a good choice when your form is large and has many controls. No one wants to scroll through a super-long form on a mobile device. By grouping controls on a screen-by-screen basis, we can improve the experience of filling out long, complex forms.
But when was the last time you developed a multi-step form? Does that even sound fun to you? There’s so much to think about and so many moving pieces that need to be managed that I wouldn’t blame you for resorting to a form library or even some type of form widget that handles it all for you.
But doing it by hand can be a good exercise and a great way to polish the basics. I’ll show you how I built my first multi-step form, and I hope you’ll not only see how approachable it can be but maybe even spot areas to make my work even better.
We’ll walk through the structure together. We’ll build a job application, which I think many of us can relate to these recent days. I’ll scaffold the baseline HTML, CSS, and JavaScript first, and then we’ll look at considerations for accessibility and validation.
I’ve created a GitHub repo for the final code if you want to refer to it along the way.
The structure of a multi-step form
Our job application form has four sections, the last of which is a summary view, where we show the user all their answers before they submit them. To achieve this, we divide the HTML into four sections, each identified with an ID, and add navigation at the bottom of the page. I’ll give you that baseline HTML in the next section.
Navigating the user to move through sections means we’ll also include a visual indicator for what step they are at and how many steps are left. This indicator can be a simple dynamic text that updates according to the active step or a fancier progress bar type of indicator. We’ll do the former to keep things simple and focused on the multi-step nature of the form.,
The structure and basic styles
We’ll focus more on the logic, but I will provide the code snippets and a link to the complete code at the end.
Let’s start by creating a folder to hold our pages. Then, create an index.html file and paste the following into it:
Open HTML
<form id="myForm"> <section class="group-one" id="one"> <div class="form-group"> <div class="form-control"> <label for="name">Name <span style="color: red;">*</span></label> <input type="text" id="name" name="name" placeholder="Enter your name"> </div> <div class="form-control"> <label for="idNum">ID number <span style="color: red;">*</span></label> <input type="number" id="idNum" name="idNum" placeholder="Enter your ID number"> </div> </div> <div class="form-group"> <div class="form-control"> <label for="email">Email <span style="color: red;">*</span></label> <input type="email" id="email" name="email" placeholder="Enter your email"> </div> <div class="form-control"> <label for="birthdate">Date of Birth <span style="color: red;">*</span></label> <input type="date" id="birthdate" name="birthdate" max="2006-10-01" min="1924-01-01"> </div> </div> </section> <section class="group-two" id="two"> <div class="form-control"> <label for="document">Upload CV <span style="color: red;">*</span></label> <input type="file" name="document" id="document"> </div> <div class="form-control"> <label for="department">Department <span style="color: red;">*</span></label> <select id="department" name="department"> <option value="">Select a department</option> <option value="hr">Human Resources</option> <option value="it">Information Technology</option> <option value="finance">Finance</option> </select> </div> </section> <section class="group-three" id="three"> <div class="form-control"> <label for="skills">Skills (Optional)</label> <textarea id="skills" name="skills" rows="4" placeholder="Enter your skills"></textarea> </div> <div class="form-control"> <input type="checkbox" name="terms" id="terms"> <label for="terms">I agree to the terms and conditions <span style="color: red;">*</span></label> </div> <button id="btn" type="submit">Confirm and Submit</button> </section> <div class="arrows"> <button type="button" id="navLeft">Previous</button> <span id="stepInfo"></span> <button type="button" id="navRight">Next</button> </div> </form> <script src="script.js"></script>
Looking at the code, you can see three sections and the navigation group. The sections contain form inputs and no native form validation. This is to give us better control of displaying the error messages because native form validation is only triggered when you click the submit button.
Next, create a styles.css file and paste this into it:
Open base styles
:root --primary-color: #8c852a; --secondary-color: #858034; body font-family: sans-serif; line-height: 1.4; margin: 0 auto; padding: 20px; background-color: #f4f4f4; max-width: 600px; h1 text-align: center; form background: #fff; padding: 40px; border-radius: 5px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); display: flex; flex-direction: column; .form-group display: flex; gap: 7%; .form-group > div width: 100%; input:not([type="checkbox"]), select, textarea width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; .form-control margin-bottom: 15px; button display: block; width: 100%; padding: 10px; color: white; background-color: var(--primary-color); border: none; border-radius: 4px; cursor: pointer; font-size: 16px; button:hover background-color: var(--secondary-color); .group-two, .group-three display: none; .arrows display: flex; justify-content: space-between align-items: center; margin-top: 10px; #navLeft, #navRight width: fit-content; @media screen and (max-width: 600px) .form-group flex-direction: column;
Open up the HTML file in the browser, and you should get something like the two-column layout in the following screenshot, complete with the current page indicator and navigation.
Adding functionality with vanilla JavaScript
Now, create a script.js file in the same directory as the HTML and CSS files and paste the following JavaScript into it:
Open base scripts
const stepInfo = document.getElementById("stepInfo"); const navLeft = document.getElementById("navLeft"); const navRight = document.getElementById("navRight"); const form = document.getElementById("myForm"); const formSteps = ["one", "two", "three"]; let currentStep = 0; function updateStepVisibility() formSteps.forEach((step) => document.getElementById(step).style.display = "none"; ); document.getElementById(formSteps[currentStep]).style.display = "block"; stepInfo.textContent = `Step $currentStep + 1 of $formSteps.length`; navLeft.style.display = currentStep === 0 ? "none" : "block"; navRight.style.display = currentStep === formSteps.length - 1 ? "none" : "block"; document.addEventListener("DOMContentLoaded", () => navLeft.style.display = "none"; updateStepVisibility(); navRight.addEventListener("click", () => if (currentStep < formSteps.length - 1) currentStep++; updateStepVisibility(); ); navLeft.addEventListener("click", () => if (currentStep > 0) currentStep--; updateStepVisibility(); ); );
This script defines a method that shows and hides the section depending on the formStep values that correspond to the IDs of the form sections. It updates stepInfo with the current active section of the form. This dynamic text acts as a progress indicator to the user.
It then adds logic that waits for the page to load and click events to the navigation buttons to enable cycling through the different form sections. If you refresh your page, you will see that the multi-step form works as expected.
Multi-step form navigation
Let’s dive deeper into what the Javascript code above is doing. In the updateStepVisibility() function, we first hide all the sections to have a clean slate:
formSteps.forEach((step) => document.getElementById(step).style.display = "none"; );
Then, we show the currently active section:
document.getElementById(formSteps[currentStep]).style.display = "block";`
Next, we update the text that indicators progress through the form:
stepInfo.textContent = `Step $currentStep + 1 of $formSteps.length`;
Finally, we hide the Previous button if we are at the first step and hide the Next button if we are at the last section:
navLeft.style.display = currentStep === 0 ? "none" : "block"; navRight.style.display = currentStep === formSteps.length - 1 ? "none" : "block";
Let’s look at what happens when the page loads. We first hide the Previous button as the form loads on the first section:
document.addEventListener("DOMContentLoaded", () => navLeft.style.display = "none"; updateStepVisibility();
Then we grab the Next button and add a click event that conditionally increments the current step count and then calls the updateStepVisibility() function, which then updates the new section to be displayed:
navRight.addEventListener("click", () => if (currentStep < formSteps.length - 1) currentStep++; updateStepVisibility(); );
Finally, we grab the Previous button and do the same thing but in reverse. Here, we are conditionally decrementing the step count and calling the updateStepVisibility():
navLeft.addEventListener("click", () => if (currentStep > 0) currentStep--; updateStepVisibility(); );
Handling errors
Have you ever spent a good 10+ minutes filling out a form only to submit it and get vague errors telling you to correct this and that? I prefer it when a form tells me right away that something’s amiss so that I can correct it before I ever get to the Submit button. That’s what we’ll do in our form.
Our principle is to clearly indicate which controls have errors and give meaningful error messages. Clear errors as the user takes necessary actions. Let’s add some validation to our form. First, let’s grab the necessary input elements and add this to the existing ones:
const nameInput = document.getElementById("name"); const idNumInput = document.getElementById("idNum"); const emailInput = document.getElementById("email"); const birthdateInput = document.getElementById("birthdate") const documentInput = document.getElementById("document"); const departmentInput = document.getElementById("department"); const termsCheckbox = document.getElementById("terms"); const skillsInput = document.getElementById("skills");
Then, add a function to validate the steps:
Open validation script
function validateStep(step)
Here, we check if each required input has some value and if the email input has a valid input. Then, we set the isValid boolean accordingly. We also call a showError() function, which we haven’t defined yet.
Paste this code above the validateStep() function:
function showError(input, message) const formControl = input.parentElement; const errorSpan = formControl.querySelector(".error-message"); input.classList.add("error"); errorSpan.textContent = message;
Now, add the following styles to the stylesheet:
Open validation styles
input:focus, select:focus, textarea:focus outline: .5px solid var(--primary-color); input.error, select.error, textarea.error outline: .5px solid red; .error-message font-size: x-small; color: red; display: block; margin-top: 2px; .arrows color: var(--primary-color); font-size: 18px; font-weight: 900; #navLeft, #navRight display: flex; align-items: center; gap: 10px; #stepInfo color: var(--primary-color);
If you refresh the form, you will see that the buttons do not take you to the next section till the inputs are considered valid:
Finally, we want to add real-time error handling so that the errors go away when the user starts inputting the correct information. Add this function below the validateStep() function:
Open real-time validation script
function setupRealtimeValidation() nameInput.addEventListener("input", () => if (nameInput.value.trim() !== "") clearError(nameInput); ); idNumInput.addEventListener("input", () => if (idNumInput.value.trim() !== "") clearError(idNumInput); ); emailInput.addEventListener("input", () => if (emailInput.validity.valid) clearError(emailInput); ); birthdateInput.addEventListener("change", () => if (birthdateInput.value !== "") clearError(birthdateInput); ); documentInput.addEventListener("change", () => if (documentInput.files[0]) clearError(documentInput); ); departmentInput.addEventListener("change", () => if (departmentInput.value !== "") clearError(departmentInput); ); termsCheckbox.addEventListener("change", () => if (termsCheckbox.checked) clearError(termsCheckbox); );
This function clears the errors if the input is no longer invalid by listening to input and change events then calling a function to clear the errors. Paste the clearError() function below the showError() one:
function clearError(input) const formControl = input.parentElement; const errorSpan = formControl.querySelector(".error-message"); input.classList.remove("error"); errorSpan.textContent = "";
And now the errors clear when the user types in the correct value:
The multi-step form now handles errors gracefully. If you do decide to keep the errors till the end of the form, then at the very least, jump the user back to the erroring form control and show some indication of how many errors they need to fix.
Handling form submission
In a multi-step form, it is valuable to show the user a summary of all their answers at the end before they submit and to offer them an option to edit their answers if necessary. The person can’t see the previous steps without navigating backward, so showing a summary at the last step gives assurance and a chance to correct any mistakes.
Let’s add a fourth section to the markup to hold this summary view and move the submit button within it. Paste this just below the third section in index.html:
Open HTML
<section class="group-four" id="four"> <div class="summary-section"> <p>Name: </p> <p id="name-val"></p> <button type="button" class="edit-btn" id="name-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>ID Number: </p> <p id="id-val"></p> <button type="button" class="edit-btn" id="id-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>Email: </p> <p id="email-val"></p> <button type="button" class="edit-btn" id="email-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>Date of Birth: </p> <p id="bd-val"></p> <button type="button" class="edit-btn" id="bd-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>CV/Resume: </p> <p id="cv-val"></p> <button type="button" class="edit-btn" id="cv-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>Department: </p> <p id="dept-val"></p> <button type="button" class="edit-btn" id="dept-edit"> <span>✎</span> <span>Edit</span> </button> </div> <div class="summary-section"> <p>Skills: </p> <p id="skills-val"></p> <button type="button" class="edit-btn" id="skills-edit"> <span>✎</span> <span>Edit</span> </button> </div> <button id="btn" type="submit">Confirm and Submit</button> </section>
Then update the formStep in your Javascript to read:
const formSteps = ["one", "two", "three", "four"];
Finally, add the following classes to styles.css:
.summary-section display: flex; align-items: center; gap: 10px; .summary-section p:first-child width: 30%; flex-shrink: 0; border-right: 1px solid var(--secondary-color); .summary-section p:nth-child(2) width: 45%; flex-shrink: 0; padding-left: 10px; .edit-btn width: 25%; margin-left: auto; background-color: transparent; color: var(--primary-color); border: .7px solid var(--primary-color); border-radius: 5px; padding: 5px; .edit-btn:hover border: 2px solid var(--primary-color); font-weight: bolder; background-color: transparent;
Now, add the following to the top of the script.js file where the other consts are:
const nameVal = document.getElementById("name-val"); const idVal = document.getElementById("id-val"); const emailVal = document.getElementById("email-val"); const bdVal = document.getElementById("bd-val") const cvVal = document.getElementById("cv-val"); const deptVal = document.getElementById("dept-val"); const skillsVal = document.getElementById("skills-val"); const editButtons = "name-edit": 0, "id-edit": 0, "email-edit": 0, "bd-edit": 0, "cv-edit": 1, "dept-edit": 1, "skills-edit": 2 ;
Then add this function in scripts.js:
function updateSummaryValues() nameVal.textContent = nameInput.value; idVal.textContent = idNumInput.value; emailVal.textContent = emailInput.value; bdVal.textContent = birthdateInput.value; const fileName = documentInput.files[0]?.name; if (fileName) const extension = fileName.split(".").pop(); const baseName = fileName.split(".")[0]; const truncatedName = baseName.length > 10 ? baseName.substring(0, 10) + "..." : baseName; cvVal.textContent = `$truncatedName.$extension`; else cvVal.textContent = "No file selected"; deptVal.textContent = departmentInput.value; skillsVal.textContent = skillsInput.value || "No skills submitted"; }
This dynamically inserts the input values into the summary section of the form, truncates the file names, and offers a fallback text for the input that was not required.
Then update the updateStepVisibility() function to call the new function:
function updateStepVisibility() formSteps.forEach((step) => document.getElementById(step).style.display = "none"; ); document.getElementById(formSteps[currentStep]).style.display = "block"; stepInfo.textContent = `Step $currentStep + 1 of $formSteps.length`; if (currentStep === 3) updateSummaryValues(); navLeft.style.display = currentStep === 0 ? "none" : "block"; navRight.style.display = currentStep === formSteps.length - 1 ? "none" : "block";
Finally, add this to the DOMContentLoaded event listener:
Object.keys(editButtons).forEach((buttonId) => const button = document.getElementById(buttonId); button.addEventListener("click", (e) => currentStep = editButtons[buttonId]; updateStepVisibility(); ); );
Running the form, you should see that the summary section shows all the inputted values and allows the user to edit any before submitting the information:
And now, we can submit our form:
form.addEventListener("submit", (e) => e.preventDefault(); if (validateStep(2)) alert("Form submitted successfully!"); form.reset(); currentFormStep = 0; updateStepVisibility(); );
Our multi-step form now allows the user to edit and see all the information they provide before submitting it.
Accessibility tips
Making multi-step forms accessible starts with the basics: using semantic HTML. This is half the battle. It is closely followed by using appropriate form labels.
Other ways to make forms more accessible include giving enough room to elements that must be clicked on small screens and giving meaningful descriptions to the form navigation and progress indicators.
Offering feedback to the user is an important part of it; it’s not great to auto-dismiss user feedback after a certain amount of time but to allow the user to dismiss it themselves. Paying attention to contrast and font choice is important, too, as they both affect how readable your form is.
Let’s make the following adjustments to the markup for more technical accessibility:
Add aria-required="true" to all inputs except the skills one. This lets screen readers know the fields are required without relying on native validation.
Add role="alert" to the error spans. This helps screen readers know to give it importance when the input is in an error state.
Add role="status" aria-live="polite" to the .stepInfo. This will help screen readers understand that the step info keeps tabs on a state, and the aria-live being set to polite indicates that should the value change, it does not need to immediately announce it.
In the script file, replace the showError() and clearError() functions with the following:
function showError(input, message) const formControl = input.parentElement; const errorSpan = formControl.querySelector(".error-message"); input.classList.add("error"); input.setAttribute("aria-invalid", "true"); input.setAttribute("aria-describedby", errorSpan.id); errorSpan.textContent = message; function clearError(input) const formControl = input.parentElement; const errorSpan = formControl.querySelector(".error-message"); input.classList.remove("error"); input.removeAttribute("aria-invalid"); input.removeAttribute("aria-describedby"); errorSpan.textContent = "";
Here, we programmatically add and remove attributes that explicitly tie the input with its error span and show that it is in an invalid state.
Finally, let’s add focus on the first input of every section; add the following code to the end of the updateStepVisibility() function:
const currentStepElement = document.getElementById(formSteps[currentStep]); const firstInput = currentStepElement.querySelector( "input, select, textarea" ); if (firstInput) firstInput.focus();
And with that, the multi-step form is much more accessible.
Conclusion
There we go, a four-part multi-step form for a job application! As I said at the top of this article, there’s a lot to juggle — so much so that I wouldn’t fault you for looking for an out-of-the-box solution.
But if you have to hand-roll a multi-step form, hopefully now you see it’s not a death sentence. There’s a happy path that gets you there, complete with navigation and validation, without turning away from good, accessible practices.
And this is just how I approached it! Again, I took this on as a personal challenge to see how far I could get, and I’m pretty happy with it. But I’d love to know if you see additional opportunities to make this even more mindful of the user experience and considerate of accessibility.
References
Here are some relevant links I referred to when writing this article:
How to Structure a Web Form (MDN)
Multi-page Forms (W3C.org)
Create accessible forms (A11y Project)
#:not#Accessibility#ADD#aria#Article#Articles#attention#attributes#background#border-radius#box#box-shadow#browser#buttons#challenge#change#classes#code#Color#content#CSS#CV#dept#direction#display#email#error handling#event#Events#Exercise
3 notes
·
View notes
Text
Cómo el CSS Transformó la Web: Una Historia de Creación y Diseño
Recorrido por un Storytelling de como el CSS a través de cada una de sus versiones revolucionó el internet que tenemos hoy en día.
https://www.patreon.com/posts/113815891
#CSS#html5#Progrmacion#web development#design#web design#Color#colors#color theory#color palette#Identificador#Border#Padding#Weidth#size#font family#font design
0 notes
Text
CSS: Más Allá de los Estilos Básicos
CSS es una herramienta indispensable para darle vida a nuestras páginas web. Sin embargo, un mal uso puede llevar a problemas de rendimiento, mantenimiento y compatibilidad. En este artículo, exploraremos los conceptos fundamentales de CSS, desde los selectores básicos hasta las convenciones de escritura, y te daremos algunos consejos para evitar errores comunes. Selectores CSS: La Base de…
#apariencia#atributo#background#border#caja CSS#clase#color#conceptos básicos#CSS#desarrollo web frontend#diseño responsive#Diseño web#diseño web moderno#elemento#elementos HTML#estilos#Flexbox#flotación#formato#fuente#fundamentos de CSS#Grid#hojas de estilo en cascada#id#introducción a CSS#layout#maquetación#maquetación web#margen#media queries
0 notes
Text
going to go to quickbooks headquarters and trash the office of whoever decided to remove the borders and alternating colors from line items in lists. how am i supposed to read anything man. i can't easily follow a line from left to right when they're all just bits of text floating in a white void
#i can re-add the colors with css but i shouldn't HAVE to because some. idk. manager decided the UI should look 'clean'#they're also so damn fond of using drop shadows as faux borders. sure it's stylish i guess but it's not solid enough for me. it feels floaty#yoshiposts
1 note
·
View note
Text
peachy keen ao3 site skin






If you'd like to add this site skin to your AO3 account, the code is under the cut.
Colours Used: pale peach: #ffeae4 darker peach: #f3c6ba yellow: #ffd7a8 orange: #ff9b75 reddish orange: #f44336 darkest orange: #8E0505
CSS:
#outer { background: linear-gradient(90deg, rgba(255,155,117,.9) 0%, rgba(255,215,168,1) 100%); }
#header .primary { background: #ff9b75; background-repeat: repeat; box-shadow: none; }
#search .button, #header .logo { display: none; }
#header .heading a, #greeting img.icon { visibility: hidden; }
#header #search .text { background: #ffeae4; border: none; box-shadow: none; width: 7em; }
#header h1.heading a::before { content: " 🍑🍑🍑"; visibility: visible; }
.splash .module h3 { border-bottom: none; color: #f44336; }
#header .menu, #small_login { background: #ffeae4; box-shadow: none; width: 20em; }
#greeting .user > li a { color: #8E0505; }
#header .menu li, .splash .news li { border-bottom: none; }
#header .actions a:hover, #header .dropdown:hover a.dropdown-toggle, #header .menu li a { background: none; color: #f44336 !important; }
#footer { background: #ff9b75; }
#main { color: #8E0505; }
#main a { color: #f44336; }
.splash .favorite li:nth-of-type(2n+1) a { background: #ffeae4; border: 1px solid #ffeae4; border-radius: 5px; }
.splash .favorite li:nth-of-type(2n+1) a:hover, .splash .favorite li:nth-of-type(2n+2) a:hover { background: #f44336; border: 1px solid #f44336; border-radius: 5px; color: #fff !important; }
.resp-sharing-button--twitter, a.resp-sharing-button__link { color: #fff !important; }
.listbox, fieldset, fieldset dl dl, fieldset fieldset fieldset, fieldset fieldset dl dl, dd.hideme, form blockquote.userstuff, .dynamic form { background: url("https://image.freepik.com/free-vector/vector-seamless-pattern-with-peaches_1015-1760.jpg"); background-repeat: repeat; border: 4px solid #fff; box-shadow: none; }
form dl { background: #ffeae4; border: 2px solid #fff; box-shadow: none; }
input, textarea { border: 1px solid #f44336; box-shadow: none; }
input:focus, select:focus, textarea:focus { background: #ffeae4; }
form dt { border-bottom: 1px solid #fff; }
form dd.required { color: #8E0505; }
.LV_invalid { background: #ffd7a8; border: 1px solid #fff; color: #f44336; box-shadow: none; }
.LV_invalid_field, input.LV_invalid_field:hover, input.LV_invalid_field:active, textarea.LV_invalid_field:hover, textarea.LV_invalid_field:active { border: 1px solid #8E0505; }
.autocomplete div.dropdown ul { background: #fff; border: 1px solid #f44336; color: #f44336; box-shadow: none; }
.autocomplete .dropdown ul li:hover, .autocomplete .dropdown li.selected { background: #f44336; color: #fff; }
.required .autocomplete, .autocomplete .notice { color: #f44336; }
.ui-sortable li { background: #ffd7a8; border: 2px solid #fff; box-shadow: none; }
.ui-sortable li:hover { background: #ff9b75; border: 2px solid #fff; box-shadow: none; }
.ui-draggable form { box-shadow: none; }
.notice, .comment_notice, .kudos_notice, ul.notes, .caution, .error, .comment_error, .kudos_error, .alert.flash, muted.notice, form.verbose legend, .verbose form legend, span.question, span.symbol, select { background: #ffeae4; color: #f44336; border: 2px solid #f44336; box-shadow: none !important; }
#modal { background: #ffeae4; border: 4px solid #ff9b75; box-shadow: none; }
#modal .content { border-bottom: none; }
.actions a:visited, .action:visited, .action a:link, .action a:visited { color: #f3c6ba; }
.actions a:hover, .actions input:hover, .actions a:focus, .actions input:focus, label.action:hover, .action:hover, .action:focus { color: #f44336; border-top: none; border-left: none; box-shadow: none; background: #f3c6ba; }
.actions a:active, .current, a.current, a:link.current, .current a:visited { color: #fff; background: #ff9b75; border-color: #fff; box-shadow: none; }
.actions label.disabled { background: #ff9b75; }
.actions .disabled select { color: #fff; border-color: #fff; }
.delete a, span.delete { color: #f44336; box-shadow: none; }
.secondary { background: #fff; border: 2px solid #f44336; box-shadow: none; }
.own, .draft, .draft .wrapper, .unread, .child, .unwrangled, .unreviewed { background: #ffeae4 !important; }
.draft { border: 2px dashed #ff9b75; }
span.unread, .replied, span.claimed, .actions span.defaulted { background: #f3c6ba; color: #f44336; border: 1px solid #fff; border-bottom: none; }
.actions span.defaulted { color: #8E0505; }
.draggable, .droppable, span.requested, .nominations .rejected { color: #8E0505; }
.nominations .approved { background: #ffeae4; }
.nominations .rejected { background: #f3c6ba; }
span.offered.requested { color: #ffeae4; }
.wrapper { box-shadow: none; }
dl.index dd { background: #f3c6ba; }
p.kudos { background: url("https://64.media.tumblr.com/14dd2ee05dbcc111dab41d6206985fe8/b1eb33fb168e0088-4b/s1280x1920/8fabca965895c42bae4d746506ffc96324eb2fd5.png"); background-repeat: no-repeat; }
.statistics .index li:nth-of-type(even) { background: #f3c6ba; }
fieldset fieldset.listbox { background: #ffeae4; border: 2px solid #ff9b75; box-shadow: none; }
.listbox>.heading, .listbox .heading a:visited { color: #f44336; }
.listbox .index { background: #ffeae4; box-shadow: none; }
dl.meta { border: 2px solid #f44336; background: #ffeae4; }
.actions a, .actions a, .action, input[type="submit"], button, .actions label, .actions a, .actions a:link, .action, .action:link, .actions input, input[type=submit], button, .actions label { background: #ffeae4; border: 1px solid #f44336; text-shadow: none; color: #f44336; }
.current, #dashboard .current { background: #f44336; border: 1px solid #fff; text-shadow: none; color: #fff; }
#dashboard.own { border-top: none; border-bottom: none; }
#dashboard a { color: #f44336 !important; }
#dashboard a:hover { background: #ff9b75; }
label { color: #f44336; }
li.blurb, fieldset ul { background: #ffeae4 !important; border: 2px solid #fff; }
#header h2.collections, .reading h4.viewed, dl.index { background: #ffeae4; color: #f44336; }
.comment h4.byline { background: #f3c6ba; border-bottom: 2px solid #fff; }
.comment div.icon { border-bottom: 5px solid #ff9b75; }
li.comment { border: 2px solid #fff; background: #f3c6ba; }
li.comment ul.actions { background: transparent !important; border: none !important; }
#stat_chart g[clip-path^=url] > g:nth-of-type(2) rect, #stat_chart svg g:nth-of-type(2) > g rect:last-of-type, #stat_chart g[clip-path^=url] > g:nth-of-type(2) rect:first-of-type { opacity: 50% !important; }
h5.fandoms.heading a, .fandom .tag, .work .fandom a.tag { font-variant: small-caps; }
.warnings .tag, .work .warning a.tag { background: #8E0505; border: 1px solid #8E0505; border-radius: 5px; color: #fff !important; padding-left: .5em; padding-right: .5em; }
.relationships .tag, .work .relationships a.tag { background: #f44336; border: 1px solid #f44336; border-radius: 5px; color: #fff !important; font-weight: bold; padding-left: .5em; padding-right: .5em; }
.characters .tag, .work .characters a.tag { background: #ff9b75; border: 1px solid #ff9b75; border-radius: 5px; color: #fff !important; font-weight: bold; padding-left: .5em; padding-right: .5em; }
.freeforms .tag, .work .freeforms a.tag { color: #f44336 !important; }
.commas li:after { content: none; }
ul.tags { line-height: 190%; }
1K notes
·
View notes
Text
ao3 skin that i made!! (copy code under "keep reading")
it's a messy combination of pieces of code from other people's skins and my own changes
the header image is NOT MINE! it is "Pattern Galaxy Space Planets Vibrant Linear Universe" by Arncil on Redbubble, which i just used as an example for an image you could use!
here are some of the skins that i can remember using as part of this, but i've been building it for years so forgive me if i forget some:
Shortening long tag fields by Xparrot (on ao3)
Slim Shaded by AO3 (on ao3)
Lily Garden by tealtiam (on Tumblr)
AO3 Tag category coloring! by ao3css (on Tumblr)
come back here to my tips or leave a comment if you need some help customizing the code!
Background color: #26303C
Text color: #CBC6C3
Header color: #46626D
Accent color: #993F33
steps to create a new skin using this code:
log into ao3 account
go to dashboard >> skins
click "create site skin"
make sure TYPE is "site skin"
add a unique title
copy all code below
paste into field 'CSS'
click on "use wizard" at the top
copy and paste the four colors written above into their corresponding boxes
click SUBMIT
click USE
how to customize this skin:
FONT SIZE: at the very top of the code, change the "90%" to be bigger or smaller to change the font size within a fic
MAIN COLORS: to change the main colors, select "use wizard" when editing the skin and replace any of the four hex codes under "Background color:", "Text color:", "Header color:", and "Accent color:"
SECONDARY COLORS: find all hex codes within the code and change those numbers as you like! i changed all colors to match with the color palette of the header photo that i chose to make it feel cohesive
TAG COLORS: towards the end, the "relationship", "character", and "freeform" tags alternate three colors to make them easy to separate. in this skin they are all very similar, so you can change those to be whatever colors you like!
HEADER PHOTO: find the link towards the end of the code right before the warning tags and replace it with a link to any photo you like! it loops, so you don't have to worry about sizing or anything
FONT: i'm unsure how exactly to do this, but the in-fic font is currently set to Georgia Serif, so i suppose just go find that and replace it with your preferred font!
BORDER STYLES: wherever you see the code "border-style:", replace the word that comes after it with one of these options: none, solid, dashed, dotted, double, groove, ridge, inset, outset, or hidden
WARNING TAGS: at the very end of the code is a list of words or phrases that, when they appear in the tags of a fic, are highlighted in a contrasting color so that they are easy to avoid if necessary. you can add or remove those tags however you like, or change the warning color!
COPY AND PASTE ALL CODE BELOW
#workskin { font-size: 90%; } li.blurb .tags { max-height: 7.5em; overflow-y: auto; } #header { min-height: 0; } #header a, #header fieldset, #header ul.primary, #header ul.primary .current { border: 0; background: 0; } h1 a img { height: 50px; border: 0; } #header .landmark { clear: none; } #header ul.primary { background: rgba(0,0,0,0.65); border-bottom: 1px solid rgba(0,0,0,0.75); } #header ul.primary, #header ul.primary .current, ul.primary.actions a, #header ul.primary .current { color: #CBC6C3; } #header ul.primary .current, #header #search input, #header #search input:focus { background: rgba(0,0,0,0.25); color: #CBC6C3; box-shadow: inset 0 0 3px #131A2A; border-color: #131A2A; } .actions, .actions input { text-transform: lowercase; } blockquote.userstuff { font-family: "Mido", "AUdimat", "Ostrich Sans Rounded","Lucida Grande", sans-serif !important; position: relative; background: rgba(0,0,0,0.1); padding: 2%; border: 1px solid rgba(0,0,0,0.15); box-shadow: 0 0 2px rgba(0,0,0,0.4); } blockquote.userstuff:after { content: "\201D"; right: 0; top: auto; left: auto; } body, .userstuff { font-family: Mido, Georgia, serif; } .heading, .userstuff h3, .userstuff h4 { font-family: "CabinSketch", Georgia,serif; } #main .heading { color: #CBC6C3; } #inner .group, #inner .heading, fieldset, .verbose legend, table, table th, col.name, span.unread, span.replied { outline: none; background: transparent; border-color: #131A2A; border-style: double; box-shadow: none; border-radius: 2em; border-bottom-right-radius: 0; border-top-left-radius: 0; } #inner .group .group .group, col.name { border-style: double; border-color: #CBC6C3; box-shadow: 0 0 2px #000; } #inner .bookmark .user.module, #inner .wrapper { border: 0; border-radius: 0; border-top: 3px double #bbb; box-shadow: none; } .filters { font-size: 90%; } .toggled form, .dynamic form, .secondary, .dropdown { background: #fff url("/images/skins/textures/tiles/white-handmade-paper.jpg"); } a.tag, a.tag:visited, a.tag:link { display: inline-block; padding: 1px 3px; margin: 2px 0px; border: 2px solid #46626D; border-radius: 5px; } .commas li:after { content: ""; } h5.fandoms.heading { color: transparent; } .favorite a.tag { border: none; } .tags li.relationships:nth-of-type(3n+1) a.tag { background-color: #1d3954; } .tags li.relationships:nth-of-type(3n+2) a.tag { background-color: #264663; } .tags li.relationships:nth-of-type(3n+3) a.tag { background-color: #305475; } .tags li.characters:nth-of-type(3n+1) a.tag { background-color: #214154; } .tags li.characters:nth-of-type(3n+2) a.tag { background-color: #294c61; } .tags li.characters:nth-of-type(3n+3) a.tag { background-color: #31576e; } .tags li.freeforms:nth-of-type(3n+1) a.tag { background-color: #234e54; } .tags li.freeforms:nth-of-type(3n+2) a.tag { background-color: #2a585e; } .tags li.freeforms:nth-of-type(3n+3) a.tag { background-color: #316269; } .tags li.freeforms a.tag:hover, .tags li.characters a.tag:hover, .tags li.relationships a.tag:hover { background-color: #26303C; color: white; } #header .logo { display: none; } #header ul.primary { box-shadow: none; padding-top: 30px; padding-bottom: 30px; background: #FCC191 url(https://i.pinimg.com/564x/8c/bc/ae/8cbcae1760dc88ae8730566337a5d2eb.jpg); background-attachment: fixed; } li.blurb a.tag[href*="suicid"], [href*="suicide"], [href*="Suicide"], [href*="rape"], [href*="Rape"], [href*="consentual"], [href*="Consentual"], [href*="non-con"], [href*="consent issues"], [href*="Kidnapping"], [href*="kidnapping"], [href*="Canibalism"], [href*="cannibalism"], [href*="Cannibalism"], [href*="Dove"], [href*="dead dove do not eat"], [href*="murder"], [href*="Murder"], [href*="harm"], [href*="self harm"], [href*="Harm"], [href*="Torture"], [href*="abduction"], [href*="asphyxiation"], [href*="blood"], [href*="Blood"], [href*="death"], [href*="Death"], [href*="gore"], [href*="Gore"], [href*="incest"], [href*="Incest"], [href*="trauma"], [href*="Trauma"], [href*="torture"] { color: #000000; font-weight: bold; background-color: #993F33; }
1K notes
·
View notes
Text
dark flat ao3 skin v2.0
1. log in and go HERE
2. click button "Create Site Skin"
3. name it whatever
4. copy/paste code from below in "CSS" field
5. "Submit"
6. make sure you clicked button "Use" HERE in the list of skins
7. change it as you like
CSS:
outer .region,
footer .group,
.post fieldset fieldset, fieldset fieldset { background: none; }
body, .group, .group .group, .region, .flash, fieldset, fieldset fieldset ul, form dl, textarea,
main .verbose legend,
.verbose fieldset, .notice, ul.notes, input, textarea, table, th, td:hover, tr:hover, .symbol .question:hover,
modal,
.ui-sortable li, .required .autocomplete, .autocomplete .notice, .system .intro, .comment_error, .kudos_error, div.dynamic, .dynamic form,
ui-datepicker-div,
.ui-datepicker table { color: #eee; border-color: #151619; outline: #111; box-shadow: none; }
form .notice, form ul.notes { box-shadow: none; }
workskin {
font-size: 1.2em; margin: auto; padding: 0 0.25em; max-width: 60em; overflow-x: auto; overflow-y: hidden; position: relative; }
.actions a, .actions a:link, .action, .action:link, .actions input, input[type="submit"], button, .current, .actions label { border-radius: 0; }
header ul.primary,
outer #footer,
.toggled form { background: #1a1b1f; }
header .primary {
background: none; padding: 10px 0; width: 100%; box-shadow: none; }
fieldset, form dl, fieldset dl dl, fieldset fieldset fieldset, fieldset fieldset dl dl, dd.hideme, form blockquote.userstuff { background: #1a1b1f !important; }
.user.navigation.actions>li { margin-top: 0.3em !important; }
header .menu,
small_login {
border: 1px solid #1f2126; box-shadow: none; padding: 0; }
.tags.group, .more.group { margin-top: 0.6em; }
header .actions a:hover,
header .actions a:focus,
header .dropdown:hover a,
header .open a,
header .menu,
small_login,
.group.listbox, fieldset fieldset.listbox, form blockquote.userstuff, input:focus, textarea:focus, li.relationships a, .group.listbox .index, .dashboard fieldset fieldset.listbox .index,
dashboard a:hover,
th,
dashboard .secondary,
.secondary, .thread .even, .system .tweet_list li, .ui-datepicker tr:hover { background: #151619; }
.userstuff p { text-align: justify; margin: 1.286em auto; padding: 0; line-height: 1.5; }
.tags.commas { margin: 1.5em auto; }
header .dropdown .menu a:hover,
header .dropdown .menu a:focus,
.splash .favorite li:nth-of-type(odd) a, .ui-datepicker td:hover,
tos_prompt .heading,
tos_prompt [disabled] {
background: #22262a; }
outer,
.javascript, .statistics .index li:nth-of-type(even),
tos_prompt,
.announcement input[type="submit"] { background: #151619; }
.filters .submit input { border: 1px solid #202227; background-color: #202227; height: 110%; margin: 1em 0; min-height: 2.286em; padding-left: 0; padding-right: 0; text-align: center; white-space: normal; }
header ul.primary,
footer,
dashboard ul,
dl.meta, .group.listbox, fieldset fieldset.listbox,
main li.blurb,
form blockquote.userstuff, div.comment, li.comment, .toggled form, form dl dt, form.single fieldset,
inner .module .heading,
.bookmark .status span, .splash .news li, .filters .group dt.bookmarker { border-color: #1a1b1f; }
.work.navigation.actions { width: 100%; }
dl.meta { border: none; }
.splash .news li { padding: 1em; }
fieldset, form dl, fieldset dl dl, fieldset fieldset fieldset, fieldset fieldset dl dl, dd.hideme, form blockquote.userstuff { padding: 1em; }
.logged-in .splash>.module { width: 100% !important; }
dl.meta { max-width: 75em; margin: auto; clear: right; padding: 2em 1.75em; position: relative; overflow: hidden; }
.group.listbox, fieldset fieldset.listbox,
main li.blurb,
.wrapper,
dashboard .secondary,
.secondary, form blockquote.userstuff, .thread .comment, .toggled form { box-shadow: none; }
dashboard .current,
.actions a:active,
outer .current,
a.current, .current a:visited, span.unread, .replied, span.claimed, dl.index dd, .own, .draft, .draft .unread, .child, .unwrangled, .unreviewed, .ui-sortable li:hover { background: #1a1b1f; border-color: #1f2126; }
greeting .menu {
right: 0; border: 1px solid #1f2126; box-shadow: none; }
select { background-color: #202227; color: #fff; border: 1px solid #202227; min-height: 3em; border-radius: 0; padding: 0 0.6em; }
input:focus, select:focus, textarea:focus { background: #202227; }
body, .toggled form, .dynamic form, .secondary, .dropdown { background: #202227; color: #fff; margin: 0; padding: 0; }
footer a:hover,
footer a:focus,
.autocomplete .dropdown ul li:hover, .autocomplete .dropdown li.selected, a.tag:hover, .listbox .heading a.tag:visited:hover, .symbol .question, .qtip-content { background: #a7a7a7; color: #111; }
.splash .favorite li:nth-of-type(odd) a:hover, .splash .favorite li:nth-of-type(odd) a:focus { background: #a7a7a7; color: #111; }
header #greeting img,
header .heading a,
header .heading a:visited,
header .user a:hover,
header .user a:focus,
header fieldset,
header form,
header p,
dashboard a:hover,
.actions a:hover, .actions input:hover, .delete a, span.delete, span.unread, .replied, span.claimed, .draggable, .droppable, span.requested, a.work, .blurb h4 a:link, .blurb h4 img, .splash .module h3, .splash .browse li a:before, .required, .error, .comment_error, .kudos_error, a.cloud7, a.cloud8,
tos_prompt .heading {
color: #a7a7a7; }
header .menu li {
border-bottom: 1px solid #2c2c2c; margin: 0; text-align: left; }
greeting .icon,
dashboard,
dashboard.own,
.error, .comment_error, .kudos_error, .LV_invalid, .LV_invalid_field, input.LV_invalid_field:hover, input.LV_invalid_field:active, textarea.LV_invalid_field:hover, textarea.LV_invalid_field:active, .qtip-content { border-color: #151619; }
dashboard.own {
border: none; }
form.filters dl { margin-left: 0; margin-right: 0; }
.filters .expander:focus { outline: none; }
.filters .expander { padding: 0.45em 0 0.45em 14px; }
.filters .group dt.search, .filters .range dt { padding: 1.25em 0 0.4em 0; }
a.tag { border-bottom: 1px dotted !important; }
a, a:link, a.tag,
header a,
header a:visited,
header .primary .open a,
header .primary .dropdown:hover a,
header .primary .dropdown a:focus,
header #search input:focus,
header #search input:hover,
dashboard a,
dashboard span,
dashboard .current,
.heading, .group .heading, .filters dt a:hover { color: #fff; }
header .dropdown .menu a {
padding: .75em .5em .75em; }
header #search .text {
background: #151619 !important; border-radius: 0; margin: 0.2857em 0.429em; }
a:visited, .actions a:visited, .action a:link, .action a:visited, .listbox .heading a:visited, span.series .divider { color: #999; }
a:active, a:focus, button:focus { outline: none; }
.actions a, .actions a:link, .action, .action:link, .actions input, input[type="submit"], button, .current, .actions label,
header .actions a {
background: #23252a; border-color: #23252a; color: #eee; box-shadow: none; text-shadow: none; }
.actions a:hover, .actions input:hover,
dashboard a:hover,
.actions a:focus, .actions input:focus,
dashboard a:focus {
color: #fff; border-color: #101214; box-shadow: none; background-color: #101214; }
.actions a:active, .current, a.current, .current a:visited { color: #fff; background: #101214; border-color: #101214; box-shadow: none; }
.delete a, span.delete { box-shadow: none; }
ul.required-tags, .bookmark .status span, .blurb .icon { opacity: 0.9; border: 0; }
outer .group .heading,
header .actions a,
fieldset.listbox .heading, .userstuff .heading, .heading, .userstuff h2 { text-shadow: none; color: #fff; background: none; }
header .actions a,
fieldset fieldset, .mce-container button, .filters .expander { box-shadow: none; }
fieldset fieldset.listbox { outline: none; }
form dd.required { color: #eee; }
.mce-container input:focus { background: #F3EFEC; }
.announcement .userstuff a, .announcement .userstuff a:link, .announcement .userstuff a:visited:hover { color: #fff; }
a, a:link, a:visited:hover { color: #fff; text-decoration: none; }
.announcement .userstuff a:visited { color: #666; }
.announcement .userstuff a:hover, .announcement .userstuff a:focus { color: #999; }
.event.announcement .userstuff a, .filters .expander { color: #eee; }
form.verbose legend, .verbose form legend { background: #151619; }
.listbox li.blurb { box-shadow: none; background: #1a1b1f; }
li.blurb, fieldset, form dl { border: none; }
li.blurb, .blurb .blurb { display: block; position: relative; clear: left; padding: 1em 1.4em; overflow: visible; background: #1a1b1f; }
dashboard ul {
float: none; display: block; padding: 0.26em 0; text-align: right; position: relative; background: none; }
user-fandoms {
padding: 1.4em 0; background: #1a1b1f; }
.listbox .index { padding: 0.6em 0; }
.bookmark div.user { background-color: #151619; }
.bookmark dl.stats { margin-bottom: 1.5em; margin-top: 1.5em; }
.dashboard .own, .comment span.unreviewed { background: #1a1b1f; opacity: 1.0; }
.own, .draft, .draft .wrapper, .unread, .child, .unwrangled, .unreviewed { background: #1a1b1f; opacity: 0.95; }
.actions a, .actions a:link, .action, .action:link, .actions input, input[type="submit"], button, .current, .actions label { padding: 0.5em 1em; border-radius: 0; }
header {
margin: 0 0 3em; }
.tags.group, .more.group { padding: 0.6em; }
dashboard a,
dashboard span {
line-height: 2.2; padding: 0 0.5em; }
.listbox>.heading, .listbox .heading a:visited { margin-left: .6em; }
.listbox, fieldset fieldset.listbox { border: 1px solid #1a1b1f; margin: 0.5em auto; box-shadow: none; }
.reading .user { margin-top: 1.5em; padding-top: 0.5em; border-top: 1px solid #23252a !important; }
.comment .userstuff { background-color: #1a1b1f !important; }
input, textarea { box-shadow: none; background: #151619; padding: 0.4em; }
.filters .indicator:before { background: #404248; color: #aaa; display: inline-block; border: 1px solid #404248; margin-right: 0.25em; background-image: none; }
.filters [type="checkbox"]+.indicator:before { padding: 0 0.25em; border-radius: 2px; }
.filters [type="checkbox"]:checked+.indicator:before { background: #970000; color: #ffffff; background-image: none; }
.filters input:checked+.indicator:before { border-color: #1a1b1f; }
.filters input:checked+.indicator+span { font-weight: 500; }
.filters .exclude [type="checkbox"]:checked+.indicator:before { background: #970000; color: #ffffff; background-image: none; }
.filters [type="radio"]:checked+.indicator:before { background: #970000; background-image: none; }
ui-datepicker-div,
.ui-datepicker table { background: #1a1b1f; }
.ui-datepicker td { border: 1px solid #23252a; }
.notice, .comment_notice, .kudos_notice, ul.notes, .caution, .error, .comment_error, .kudos_error, .alert.flash { background: #2e3138; border: 1px solid #2e3138; margin: 0.6em auto; padding: 1em; box-shadow: none; border-radius: 0; }
.listbox .index { padding: 0.6em; box-shadow: none; }
dl.meta { max-width: 75em; background: #1a1b1f; margin-top: 1em; }
dl.index dd { background: #151619 !important; }
form.search input[type="text"] { border-top-color: #151619; background-color: #202227; padding: 0.45em 0.45em; border-radius: 0; }
modal {
background: #1a1b1f; border: 10px solid #1a1b1f; margin: 3% 0; max-width: 800px; min-width: 200px; padding-bottom: 44px; position: relative; text-align: left; width: 80%; z-index: 501; }
.post .meta dd ul li { display: block; padding-bottom: 0.6em; }
workskin {
font-size: 1.2em; max-width: 52em; }
div.comment, li.comment { padding: 0.6em; background: #1a1b1f !important; }
193 notes
·
View notes
Text
So I created an ao3 skin and I would like to share it for anyone who wants to use it 💞
Here’s the code >>>
•Wizard Settings
Can be overridden by custom CSS :
Background color:
#FCEBFC
Text color:
#AF7E98
Header color:
#B34A81
Accent color:
#EABEE4
•CSS:
:root {
--background-color: #f9e3f2;
--text-color: #4d494a;
--form-background: #fdeff5;
}
body {
font-family: sans-serif;
}
.wrapper {
background-color: white;
border: 2px solid #f3c2e3;
}
#header {
padding: 10px;
margin-bottom: 15px;
}
#header a {
text-decoration: none;
}
#header a:hover {
text-decoration: underline;
}
#header ul.navigation.actions.user.signed-in {
display: flex;
justify-content: flex-end;
padding: 10px;
}
#main {
padding: 20px;
}
.heading {
padding: 8px;
margin-bottom: 10px;
font-weight: bold;
}
input[type="text"],
input[type="date"],
textarea,
select {
border: 1px solid #f3c2e3;
padding: 8px;
margin: 5px 0;
}
input[type="radio"],
input[type="checkbox"] {
margin-right: 5px;
}
.button,
input[type="submit"],
button {
border: none;
padding: 10px 20px;
cursor: pointer;
border-radius: 4px;
margin-bottom: 5px;
}
.button:hover,
input[type="submit"]:hover,
button:hover {
background-color: #e687b0;
}
#new_work_form .actions .button {
border: none;
padding: 10px 20px;
margin: 5px 5px 5px 0;
cursor: pointer;
border-radius: 4px;
}
.actions .button.current {
border: none;
padding: 10px 20px;
margin: 5px 5px 5px 0;
cursor: pointer;
border-radius: 4px;
}
#work_search_form .submit .button {
border: none;
padding: 10px 20px;
margin: 5px 0;
cursor: pointer;
border-radius: 4px;
}
#work_search_form .submit .button:hover {
background-color: #e687b0;
}
I decided to write it down for easier access🌸
I’ll leave a Reddit link below ⬇️ that explains how to use the code if it’s your first time easily. Credit to @tired-library-ghost on Reddit for this amazing explanation ❤️

67 notes
·
View notes
Text
Dark Mode Work Skin for the fic To Be a Dragon Among Men
This is the code and urls for the custom dark mode work skin I made for my fic To Be a Dragon. Feel free to use it for your own works or for site skins, just remember to credit my user if you do.
[EDIT 25-03-18: Fixed padding for .frameborder class]
[EDIT 25-06-12: Added formatting rules for .poetry class and <p>]
Additional Resources
A Step-by-Step Guide to Work Skins from AO3 News - A great basic guide to what work skins are and how to make one.
How to Apply Work Skins to Others' Works by classygreydove - This is a guide I made on how to make a work skin into a site skin. You'll need to know this if you want to apply the work skin to any fic you want to read.
How to Change Work Skin Font by classygreydove - Don't like the font I use for the work skin? Don't worry, I'll show you how to change it.
Light Mode CSS - You can find the code for the Light Mode work skin here.
Light and Dark Mode Backgrounds - You can find the background images for the Light and Dark Mode work skins here.
Other Background Options - Here are a few mid-tone backgrounds that will have a lower contrast to the text.
Line Breaks (for Phone) - Do you like the custom dragon line breaks? Here's the phone-sized ones.
Line Breaks (for Wide Screens) - Do you like the custom dragon line breaks? Here's the laptop-sized ones.
[Code begins under Keep reading break]
#workskin .userstuff .hr, #workskin .hr, #workskin hr { height: 36px; width: 178px; background: url(https://64.media.tumblr.com/f19653c8c877dbe7a14e78434f1d0df6/d0f8688c32033f2d-b3/s250x400/6edcdac1e5614693d10491cff0725fd3633de77e.png); background-repeat: no-repeat; background-position: center; border: 0; }
#workskin { background: url(https://64.media.tumblr.com/f20ef324c5117a56d7dd2c8aa7e45151/4dcdf7c3c32cb0d1-68/s2048x3072/10c1120c78cd66a99c1067e6ed8b1addcd52ef57.png); background-repeat: repeat-y repeat-x; background-position: top; color: rgba(255, 255, 248, 0.85) !important; font-family: 'Georgia', 'Lucida Grande', 'Verdana'; }
#workskin a { background: linear-gradient(135deg, #b4853f 0%, #edc967 40%, #b4853f 80%, #705103 100%) !important; -webkit-background-clip: text !important; -webkit-text-fill-color: transparent !important; border-bottom: 0px; }
#workskin a:hover, #workskin a:active { background: linear-gradient(135deg, #b4853f 10%, #edc967 60%, #b4853f 80%, #705103 100%) !important; -webkit-background-clip: text !important; -webkit-text-fill-color: transparent !important; }
#workskin h2, #workskin h3 { line-height: 1.25; font-variant: small-caps; }
#workskin .userstuff blockquote { display: block; border: 2px solid #b4853f; border-image: linear-gradient(135deg, #b4853f 0%, #edc967 40%, #b4853f 80%, #705103 100%); border-image-slice: 1; padding: 15px 15px 15px 15px; margin-left: 1.5em; margin-right: 1.5em; }
#workskin .goldborder { display: block; border: 2px solid #b4853f; border-image: linear-gradient(135deg, #b4853f 0%, #edc967 40%, #b4853f 80%, #705103 100%); border-image-slice: 1; padding: 15px 15px 15px 15px; }
#workskin .frameborder { border: 2px solid #b4853f; border-image: linear-gradient(135deg, #b4853f 0%, #edc967 40%, #b4853f 80%, #705103 100%); border-image-slice: 1; padding: 0px; }
#workskin .mobilebreak { width: 178px; max-width: 100%; max-height: 100%; display: block; margin-left: auto; margin-right: auto; }
#workskin .textlink { font-variant: small-caps; }
#workskin .notesheading { font-size: 120%; font-variant: small-caps; font-family: 'Georgia', 'Lucida Grande', 'Verdana'; line-height: 2; }
#workskin .triggerwarning { color: rgba(240, 240, 240, 0.9); border-radius: 5px; background: rgba(128, 0, 0, 0.8); padding-left: 2px; padding-right: 2px; font-weight: bold; font-variant: small-caps; }
workskin .userstuff p { margin: 0; }
workskin .poetry { margin-inline-start: 1.5em; }
#ao3 skins#ao3 writer#ao3 fanfic#ao3 work skin#dark mode#the untamed#mo dao zu shi#To Be a Dragon Among Men
27 notes
·
View notes
Text
Learn How to Build a WordPress Block Theme Style Variation — Speckyboy
New Post has been published on https://thedigitalinsider.com/learn-how-to-build-a-wordpress-block-theme-style-variation-speckyboy/
Learn How to Build a WordPress Block Theme Style Variation — Speckyboy
WordPress block themes offer plenty of flexibility. You can make style and layout changes within your web browser – no coding knowledge is required. They can also include extras like block patterns and style variations.
Style variations give you a head start on design. They allow us to create multiple color and typography combinations. They also house custom block styles defined in the Site Editor. Anything in a theme.json file can also be included in a style variation.
This is handy for web professionals and users alike. Choose the variation that suits your needs and start building your site.
Creating a custom block theme style variation is easier than you think. The entire process takes place in the WordPress Site Editor. A simple variation can be built in minutes.
So, follow along as we build a style variation! We’ll show you how to point and click your way to a custom design.
Style Variation Project Requirements
The requirements for building a custom style variation are minimal. You’ll need:
We don’t recommend using a production website for this process. A staging or local WordPress installation is the safer way to go.
Let’s Build a Style Variation
Now, it’s time to start building! Log in to your WordPress website and follow the steps below.
Step 1: Open the WordPress Site Editor
First, navigate to Appearance > Editor in the WordPress admin to open the Site Editor. Then, click the Styles link in the left sidebar.
The Styles panel includes links for Typography, Colors, Background, Shadows, and Layout. You’ll also find a Browse Styles link that displays available style variations for the theme.
Finally, the Blocks link allows you to customize individual block styles across the site.
Step 2: Change Your Theme’s Styles
This step is all about personal preference. Work your way through the Styles panel and start making changes.
Color and typography are the most obvious changes, but you can take things further. For example, you can change the layout width and spacing. Plus, every block included with WordPress can be customized. Add margins, padding, borders, or custom CSS.
We covered the basics in our variation, including:
Created a custom color palette;
Installed new fonts from Google Fonts;
Added custom spacing for the Group and Paragraph blocks;
Changed the look of the Button block;
The result is an earthy look that aims for simplicity. But you can do as much or as little as you like. Just remember to save your changes when done.
Step 3: Save Your Style Variation
Our next task involves saving our custom style variation. This functionality is part of the Create Block Theme plugin.
The feature is located within the Site Editor. Here’s how to find it:
While in the Site Editor, click on the right panel, highlighted in green below:
Click the wrench icon on the upper right of the screen and select Create Theme Variation:
Name the variation and ensure the Save Fonts box is checked. We’ll call ours “Beautiful Earth.”
Click the Create Theme Variation button to save the settings.
Once saved, the new variation is added to the list in the Browse Styles area of the theme editor. Hovering over the variation reveals its name.
How to Use Your Style Variation on Another Site
Style variations are portable and can be used on multiple websites. The process involves copying the generated JSON file and adding it to the desired site.
Locate the style variation’s JSON file in /wp-content/your-theme/styles/ Replace your-theme with the name of the theme you’re using (ours is twentytwentyfive).
For reference, our JSON file is called beautiful-earth.json
Copy your style variation’s JSON file.
On your new website, paste the file into /wp-content/your-theme/styles/ – you may need to upload the file via SFTP or your web host’s file manager.
You’ll now be able to choose the style variation within the Site Editor.
About Custom Fonts
Earlier, we mentioned the ability to add custom fonts to a style variation. It requires a few extra steps to work when moving your variation to a new site.
Locate the custom fonts you added at /wp-content/themes/your-theme/assets/fonts/
Copy each font’s respective folder.
Paste the font folders into the same directory on your new site. Once again, you may need to upload them.
Give Your Block Theme a Custom Look
Style variations are a convenient way to add personality to your block theme. You can build them to suit your project requirements.
They also act as a starting point for designers. You can continue to add custom styles after applying a variation. The changes you make will be saved in the site’s database.
There’s also an option to reset the styles to the variation’s defaults. That makes it easy to experiment without losing the key elements of your design.
The best part is that style variations don’t require coding expertise. That puts custom design within everyone’s reach.
Related Articles
Related Topics
Written by Eric Karkovack
Eric Karkovack is a web designer and WordPress expert with over two decades of experience. You can visit his business site here. He recently started a writing service for WordPress products: WP Product Writeup. He also has an opinion on just about every subject. You can follow his rants on Bluesky @karks.com.
Read more articles by Eric Karkovack
#ADD#admin#Articles#assets#background#borders#box#browser#Building#Business#change#coding#Color#colors#content#CSS#Database#Design#designers#displays#earth#easy#folders#fonts#Google#google fonts#green#how#how to#How to Use
1 note
·
View note
Text
CÓDIGO #130 | Change of Pace.
LIVE PREVIEW & DOWNLOAD.
♦ Quinto prompt del Codember 2023 (Seasons) de @elalmacen-rp. Una tablilla que sirve tanto para búsquedas como para listas de grupos, con acento personalizado para cada pestaña. Tiene 4 pestañas por defecto, pero se pueden añadir más (instrucciones bajo el cut). ♦ No quites los créditos ni uses como base. ♦ Todos los colores y fuentes son modificables. Si no sabéis cambiar algo, preguntadme por ask y os echaré una mano.
Si quieres retirar pestañas: Quita los inputs, labels y [role=“box”] que no te hagan falta.
Si quieres agregar pestañas: Añade un input con un id nuevo (recomiendo usar numerados), label nuevo con for igual al id del input y un [role=“box”] con number igual al id del input.
A continuación agrega este CSS en tu <style>:
.cd23-seasons input#cd23s-XX:checked ~ * { –tab:YY; }
El XX sería el número que has puesto en tu input, y en tab vas a poner ese número menos 1. Por ejemplo, si es tu pestaña 5, sería #cd23-c5, y –tab sería igual a 4. A continuación, añadirás esto:
.cd23-seasons input#cd23s-XX:checked ~ [role="tabs"] label[for="cd23s-XX"] { background: var(--_tabs-color); border-color: var(--_tabs-color); }
Siendo XX, de nuevo, el número que has puesto en tu input.
#ncodes#codember2023#dohtml#dohtml template#html#rpg#html template#rpg template#ncwanted#ncadmin#ncmulti
139 notes
·
View notes
Text
crossposting some cool behind the scenes from evil bajillionaire website X:
this is one of my favorite 3D CSS rooms currently in corru.observer! the ceiling does all the lifting in making the room seem curved, when really it's just made up of squares. it's HTML, so the walls are all flat and straight planes - the ceiling just has a border-radius set!
these are some other shots from the outside - the magenta parts of the walls are actually transparent, which is what gives them their color (from the page background) and lets the ceiling do its little visual trick.
130 notes
·
View notes
Text
Day 2 - 100 Days CSS Challenge
Welcome to day 2 of 100 days of css challenge, where we will be together getting a given image result into reality by code.
We already know the drill since we did the first challenge, now let's get right into the different steps:
First step : Screenshot the image and get its color palette
No crazy color palette here, we only have two colors
White
This shade of green: #3FAF82
To make things more organized and get used to coding in an organized way, even if not doing it here wouldn't make any difference because we only have two colors, in more complex projects we would have a lot, we will define our colors at the beginning of our CSS code (well, only the green in this case):
:root { --main-green: #3FAF82; }
And this is how we'll use it whenever we want:
color: var(--main-green);
Second step : Identify the image elements
What elements do I have?
Three lines: line1, line 2, and line 3. I'll add them to my HTML starter template, again I'll leave the frame and center there:
<div class="frame"> <div class="center"> <div class="line-1 line"></div> <div class="line-2 line"></div> <div class="line-3 line"></div> </div> </div>
Third step : Bring them to life with CSS
Applying the background color
Only one line should be changed in the CSS code already added to .frame class:
background: var(--main-green);
So this is what we have going on for now :
Creating the lines
Now let's create our lines; if you noticed I gave each one two classes line-number and then line. I'll use the line class to give them all the common properties they have such as the color, height, width, position, border-radius, and shadow. And then I'll use the line-number to move them wherever I want using the left, top, right, bottom properties of an absolutely positioned element in CSS.
Let's start by creating all of them:
.line { left: -45px; position: absolute; height: 9px; width: 100px; background: white; border-radius: 10px; box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.2); }
And just like this you'll see this in the browser:
You only see one line because the three are overlapping each other, and that's why we'll move each one of them exactly where we want using this:
.line-3 { top: 22px; } .line-1 { top: -22px; }
Now our static menu is ready:
Creating and analyzing the animations
As of observing, we can see that:
Line one goes down to line 2
Line three goes up to line 2
THEN line 2 disappears
THEN lines 1 and rotate to create the X
line-one-goes-down animation
This is my line-one code in the static version:
.line-1 { top: -22px; }
What I'm trying to do here is simply a movement translated by changing top from -22px to it becoming 0px:
@keyframes line-one-goes-down { 0% { top: -22px; } 100% { top: 0px; } }
line-three-goes-up animation
Again, I'm trying to go from top being 22px to it being 0px:
@keyframes line-three-goes-up { 0% { top: 22px; } 100% { top: 0px; } }
line-two-disappear animation
Making disappear simply means turning its opacity and width to 0:
@keyframes line-two-disappear { 0% { opacity: 1; width: 100px; } 100% { opacity: 0; width: 0px; } }
I'm gonna apply these animations and see what happens , before I create the rotation animations
.center.active .line-1 { animation: line-one-goes-down 0.5s forwards; } .center.active .line-2 { animation: line-two-disappear 0.5s forwards; } .center.active .line-3 { animation: line-three-goes-up 0.5s forwards; }
forwards means that the element will stay in the final state after the animation and not return to its original state.
This is what applying those three animations looks like:
Last but not least : let's Create the X
We only have to animations left for this: rotate-line-1 and rotate-line-2. Let's create them:
@keyframes rotate-line-1 { 0% { transform: rotate(0deg); } 100% { transform: rotate(45deg); } } @keyframes rotate-line-2 { 0% { transform: rotate(0deg); } 100% { transform: rotate(-45deg); } }
And that is my friends how we finished this challenge!
Happy coding, and see you tomorrow for Day 3!
#100dayscssChallenge#codeblr#code#css#html#javascript#java development company#python#studyblr#progblr#programming#comp sci#web design#web developers#web development#website design#webdev#website#tech#html css#learn to code
18 notes
·
View notes
Text
simple ao3 skin





made this while procrastinating my final project
parent skin: zebra mono (ao3 public skin)
font, font size, and margin width edited with wizard (can be easily changed!)
css code: below the break!
header ul.primary,
footer,
.autocomplete .dropdown ul li:hover, li.selected, a.tag:hover { background: #000 url('https://i.pinimg.com/736x/a5/9d/f7/a59df777843458ba08859f8cb2b0b027.jpg'); background-size: 500px; }
footer ul,
header .primary a {
background: #AA336A; }
header .primary a:hover {
background: #FFF5EE; }
header .heading a,
header .actions a:hover,
header .actions a:focus,
header .dropdown:hover a,
header .open a,
header fieldset,
header form,
header p,
dashboard a:hover,
.actions a:hover, .actions input:hover, .delete a, span.delete, span.unread, .replied, span.claimed, .draggable, .droppable, span.requested, a.work, .blurb h4 a:link, .blurb h4 img, .system .latest h3, .system div.news h3, .system .tweets h3, .required, .error, a.cloud7, a.cloud8 { color: #000; }
outer #header #greeting .icon,
dashboard.own,
.error, .comment_error,
header ul.primary,
.LV_invalid, .LV_invalid_field, input.LV_invalid_field:hover, input.LV_invalid_field:active, textarea.LV_invalid_field:hover, textarea.LV_invalid_field:active,
header .primary a,
header .primary .current,
header .primary input,
header .search input {
border-color: #000 !important; }
.icon { background: none; }
#lesbian colors!! bless up!!#(it was an accident but nobody has to know that)#ao3#ao3 skins#archive of our own#pink#orange#white#Zebra Mono#simple#meso-z
12 notes
·
View notes
Text
css border-image
proce55ing convolution emboss
gimp spiral
mspaint
this ^ is the "border image". The middle "tjenis penis" section is replaced entirely with the html content (in this case - elis drawing). A browser will tile the dark/cross-section to fit whatever is inside the frame. I don't know what kind of effect this is meant to be used for but it's very neat.
border-width: 163px 102px 171px 122px; border-style: solid; border-color: transparent; border-image-source: url('web-cuccoo2.png'); border-image-slice: 163 102 171 122; border-image-repeat: round;
17 notes
·
View notes
Note
would you be willing to share a neocities tutorial?
WELL basics i know of CSS/HTML (and i must stress this is BASICS, i am also a n00b) that would have saved me a LOT of headache is the code will have a <head> and <body> section
the <head> section will contain the CSS styling, and the <body> contains the actual content of the site. for example, to create the boxes containing text, this is a <style> tag within my <head> section, containing the CSS specifications for the default font color and size, as well as the box's size and border.
then, in the <body> section i can put <div id="box"> tag, telling the code "hey, this part of the CSS is what i want this to look like"
mines all super messy because i patchworked it together/wrote it from scratch and know nothing about html lol. last time i did anything like this was coding my deviantart page in 2014. but this was the biggest hurdle for me that was making me not understand what was going on
#there are some free layout builders and better written tutorials elsewhere on the internet i am sure...#dia answers
27 notes
·
View notes